One important area of application for information theory is time series analysis. Here, we will demonstrate how to compute the modes of information flow --- intrinsic, shared, and synergistic --- between the two dimensions of the tinkerbell attractor.
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import dit
from dit.inference import binned, dist_from_timeseries
from dit.multivariate import total_correlation as I, intrinsic_total_correlation as IMI
dit.ditParams['repr.print'] = True
Here we define a few constants for this notebook:
In [2]:
TRANSIENTS = 1000
ITERATIONS = 1000000
BINS = 3
HISTORY_LENGTH = 2
In [3]:
def tinkerbell(x=None, y=None, a=0.9, b=-0.6013, c=2.0, d=0.5):
if x is None:
x = np.random.random() - 1
if y is None:
y = np.random.random() - 1
while True:
x, y = x**2 - y**2 + a*x + b*y, 2*x*y + c*x + d*y
yield x, y
And then we generate the time series:
In [4]:
tb = tinkerbell()
# throw away transients
[next(tb) for _ in range(TRANSIENTS)]
time_series = np.asarray([next(tb) for _ in range(ITERATIONS)])
And we plot the attractor because it's pretty:
In [5]:
plt.figure(figsize=(8, 6))
plt.scatter(time_series[:,0], time_series[:,1], alpha=0.1, s=0.01)
Out[5]:
In [6]:
binary_time_series = binned(time_series, bins=BINS)
In [15]:
print(binary_time_series[:10])
In [7]:
time_series_distribution = dist_from_timeseries(binary_time_series, history_length=HISTORY_LENGTH)
In [8]:
time_series_distribution
Out[8]:
Finally, we assign helpful variable names to the indicies of the distribution:
In [9]:
x_past = [0]
y_past = [1]
x_pres = [2]
y_pres = [3]
In [16]:
intrinsic_x_to_y = IMI(time_series_distribution, [x_past, y_pres], y_past)
time_delayed_mutual_information_x_to_y = I(time_series_distribution, [x_past, y_pres])
transfer_entropy_x_to_y = I(time_series_distribution, [x_past, y_pres], y_past)
shared_x_to_y = time_delayed_mutual_information_x_to_y - intrinsic_x_to_y
synergistic_x_to_y = transfer_entropy_x_to_y - intrinsic_x_to_y
In [17]:
print(f"Flows from x to y:\n\tIntrinsic: {intrinsic_x_to_y}\n\tShared: {shared_x_to_y}\n\tSynergistic: {synergistic_x_to_y}")
In [18]:
intrinsic_y_to_x = IMI(time_series_distribution, [y_past, x_pres], x_past)
time_delayed_mutual_informtaion_y_to_x = I(time_series_distribution, [y_past, x_pres])
transfer_entropy_y_to_x = I(time_series_distribution, [y_past, x_pres], x_past)
shared_y_to_x = time_delayed_mutual_informtaion_y_to_x - intrinsic_y_to_x
synergistic_y_to_x = transfer_entropy_y_to_x - intrinsic_y_to_x
In [19]:
print(f"Flows from y to x:\n\tIntrinsic: {intrinsic_y_to_x}\n\tShared: {shared_y_to_x}\n\tSynergistic: {synergistic_y_to_x}")
In [ ]: